﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Data.NHibernate.Generic.Support;
using System.Collections;
using Cn.Edwon.Data;
using NHibernate.Criterion;
using NHibernate;

namespace Cn.Edwon.Spring {
    /// <summary>
    /// 通用的数据操作方法
    /// </summary>
    public class DaoSupport : HibernateDaoSupport {

        
        #region 常用方法
        public Object Save(String entityName,Object eo) {
            return HibernateTemplate.Execute<Object>(delegate(ISession session) {
                return session.Save(entityName, eo);
            });
        }
        public Object Save<T>(T eo) {
            return HibernateTemplate.Save(eo);
        }

        public void Update(String entityName,Object eo) {
            HibernateTemplate.Execute<Object>(delegate(ISession session) {
                session.Update(entityName, eo);
                return null;
            });
            HibernateTemplate.Update(eo);
        }
        public void Update<T>(T eo) {
            HibernateTemplate.Update(eo);
        }

        public void Update<T>(T eo,LockMode lm) {
            HibernateTemplate.Update(eo,lm);
        }

        public void Delete(Type entityType, Object eo) {
            HibernateTemplate.Execute<Object>(delegate(ISession session) {
                session.Delete(entityType.Name, eo);
                return null;
            });
        }
        public void Delete(Type entityType, IList keys) {
            HibernateTemplate.Execute<Object>(delegate(ISession session) {
                IQuery q = session.CreateQuery("delete " + entityType.Name + " where id in (:Keys)");
                q.SetParameterList("Keys", keys);
                q.ExecuteUpdate();
                return null;
            });
        }
        public IList<Object> ExcuteSqlQuery(String rSql) {
            return HibernateTemplate.ExecuteFind<Object>(delegate(ISession session) {
                IQuery q = session.CreateSQLQuery(rSql);
                return q.List<Object>();
            });
        }
        public void ExcuteSqlUpdate(String rSql) {
            HibernateTemplate.Execute<Object>(delegate(ISession session) {
                IQuery q = session.CreateSQLQuery(rSql);
                q.ExecuteUpdate();
                return null;
            });
        }
        public void Delete<T>(T eo) {
            HibernateTemplate.Delete(eo);
        }
        public void Delete(string queryString) {
            HibernateTemplate.Delete(queryString);
        }

        public IList<Object> LoadAll(Type entityType) {
            return HibernateTemplate.ExecuteFind<Object>(delegate(ISession session) {
                IQuery q = session.CreateQuery("from " + entityType.Name);
                return q.List<Object>();
            });
        }
        public IList<Object> LoadAll(Type entityType,String rOwkerKey) {
            return HibernateTemplate.ExecuteFind<Object>(delegate(ISession session) {
                IQuery q = session.CreateQuery("from " + entityType.Name +" eo where eo.OwnerKey='"+rOwkerKey+"'" );
                return q.List<Object>();
            });
        }
        public IList<Object> Load(Type entityType, String Pk, Int32 page, Int32 pageSize, IList<ICriterion> findCondition, IList<Order> orderCondition) {
            return HibernateTemplate.ExecuteFind<Object>(delegate(ISession session) {
                ICriteria crit = session.CreateCriteria(entityType);
                if (findCondition != null && findCondition.Count>0) {
                    foreach (ICriterion cri in findCondition) {
                        crit.Add(cri);
                    }
                }
                if (orderCondition != null && orderCondition.Count > 0) {
                    foreach (Order order in orderCondition) {
                        crit.AddOrder(order);
                    }
                }
                ICriteria pcrit = CriteriaTransformer.Clone(crit);
                CountProjection cp = Projections.Count(Pk);
                Int32 totalCount = Convert.ToInt32(pcrit.SetProjection(cp).UniqueResult());
                
                if (page < 1) page = 1;
                if (pageSize < 1) pageSize = 1;
                Int32 totalPage = Convert.ToInt32(Math.Ceiling(1.0*totalCount / pageSize));
                if (page > totalPage) page = totalPage;

                crit.SetFirstResult((page-1) * pageSize).SetMaxResults(pageSize);
                IList<Object> list = crit.List<Object>();
                if (list == null)
                    list = new List<Object>();
                list.Insert(0,totalCount);
                return list;
            });
        }
        public IList<T> LoadAll<T>() {
            return HibernateTemplate.LoadAll<T>();
        }

        public T Load<T>(Object key) {
            return HibernateTemplate.Load<T>(key);
        }

        public void Load(Object eo,Object key) {
            HibernateTemplate.Load(eo, key);
        }

        public IList<T> Find<T>(string queryString) {
            return HibernateTemplate.Find<T>(queryString);
        }

        public IList<Object> Find(string queryString,int top) {
            return HibernateTemplate.ExecuteFind<Object>(delegate(ISession session) {
                IQuery q = session.CreateQuery(queryString);
                if(top>0)
                    q.SetMaxResults(top);
                return q.List<Object>();
            });
        }

        public IList<T> Find<T>(string queryString,Object[] values) {
            return HibernateTemplate.Find<T>(queryString, values);
        }

        public int ExecuteUpdate(String rHql) {
            return HibernateTemplate.Execute<int>(delegate(ISession session) {
                IQuery q = session.CreateQuery(rHql);
                return q.ExecuteUpdate();
            });
        }
        public IList<Object> Search(string entityName,IList<SearchCase> sclist) {
            return HibernateTemplate.ExecuteFind<Object>(delegate(ISession session) {
                String hql = "from " + entityName;
                for (int i = 0; i < sclist.Count; i++) {
                    hql += (i == 0) ? " where " : " and ";
                    SearchCase sc = sclist[i];
                    if (sc.Express == Express.Eq) {
                        hql += sc.Column + " = :" + sc.Column;
                    }else if (sc.Express == Express.Like) {
                        hql += sc.Column + " like :" + sc.Column;
                    }
                }
                log.Debug(hql);
                IQuery q = session.CreateQuery(hql);
                foreach (SearchCase sc in sclist) {
                    q.SetParameter(sc.Column, "%"+sc.Value+"%");
                }
                return q.List<Object>();
            });
        }
        
        #endregion
    }
}
